/*******************************************************************************
        
        copyright:		Copyright (C) Mike Reinhold 2010. All rights reserved
        				
        license:		BSD style: $(LICENSE)
        		
        author(s): 		Mike Reinhold.
        				
*******************************************************************************/
module tango.util.cipher.pad.ISO_IEC9797_1;

import tango.util.cipher.Cipher;

/** Implements the ISO IEC9797.1 padding scheme */
class ISO_IEC9797_1: BlockCipherPadding {

	ISO_IEC9797_1 dup() {
		return new ISO_IEC9797_1();
	}
	
	/***************************************************************************
	
			name
			
			Returns:
			The name of the padding scheme			

	***************************************************************************/
	string name() {
		return "ISO-IEC 9797-1";
	}
	
	/***************************************************************************
	
			allowsReordering
			
			Returns:
			does the padding allow safe reordering?
			
			Remarks:
			See the classes in tango.util.cipher.order for further details. 

	***************************************************************************/
	bool allowsReordering(){
		return true;
	}

	/***************************************************************************
	
			pad
			
			Params:
			len = number of pad bytes to be generated
			
			Returns:
			a ubyte array containing the padding bytes

	***************************************************************************/
	ubyte[] pad(uint len) {
		ubyte[] pad = new ubyte[len];

		// set pad bytes to zeros
		pad[1 .. len] = 0;

		// set first pad byte to a single bit followed by zeros
		if(len > 0)
			pad[0] = cast(ubyte) 0x80;

		return pad;
	}

	/***************************************************************************
	
			unpad
			
			Params:
			input_ = the padded text
			
			Returns:
			the number of pad bytes.

	***************************************************************************/	
	uint unpad(void[] input_) {
		auto input = cast(ubyte[]) input_;
		int pos;

		//last padding byte should be 0x80
		for(pos = input.length - 1; input[pos] == 0; pos--) {}

		return cast(uint) (input.length - pos); // the number of pad bytes
	}
} 